home *** CD-ROM | disk | FTP | other *** search
- /*
- ** dispatch.c - dispatcher for REKO DataType class
- ** Copyright © 1995 Michael Letowski
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <dos/dos.h>
- #include <graphics/displayinfo.h>
- #include <graphics/gfx.h>
- #include <graphics/modeid.h>
- #include <intuition/classes.h>
- #include <datatypes/datatypesclass.h>
- #include <datatypes/pictureclass.h>
- #include <utility/hooks.h>
- #include <support/types.h>
-
- #include <string.h>
-
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <proto/datatypes.h>
- #include <proto/graphics.h>
- #include <proto/intuition.h>
- #include <proto/utility.h>
-
- #include "classbase.h"
- #include "dispatch.h"
-
- #define HCNT 13 /* Number of cards horizontally */
- #define VCNT 4 /* Number of cards vertically */
- #define REKO_I 55 /* Cards in REKO I cardset */
- #define REKO_II 59 /* Cards in REKO II cardset */
-
- struct Map
- {
- ULONG map_X;
- ULONG map_Y;
- };
-
- STATIC ASM Object *Dispatch(R_A0 Class *cl, R_A2 Object *o, R_A1 Msg msg);
- //STATIC ASM LBOOL GetREKO(R_A6 struct ClassBase *cb, R_A0 Class *cl,
- // R_A2 Object *o, R_A1 struct TagItem *attrs);
- STATIC LBOOL GetREKO(struct ClassBase *cb, Object *o, struct TagItem *attrs);
- STATIC VOID GetXY(ULONG num, ULONG *x, ULONG *y);
- STATIC ULONG LocSetDTAttrs(struct ClassBase *cb, Object *o, ULONG data, ...);
- STATIC ULONG LocGetDTAttrs(struct ClassBase *cb, Object *o, ULONG data, ...);
-
- Class *InitClass(struct ClassBase *cb)
- {
- Class *CL;
-
- /* Create our class (no instance) */
- if(CL=MakeClass(REKODTCLASS,PICTUREDTCLASS,NULL,NULL,0))
- {
- CL->cl_Dispatcher.h_Entry=(HOOKFUNC)Dispatch;
- CL->cl_UserData=(ULONG)cb;
- AddClass(CL);
- }
- return(CL);
- } /* InitClass */
-
- STATIC ASM Object *Dispatch(R_A0 Class *cl, R_A2 Object *o, R_A1 Msg msg)
- {
- struct ClassBase *cb=(struct ClassBase *)cl->cl_UserData;
- Object *Obj;
-
- switch(msg->MethodID)
- {
- case OM_NEW: /* We know this method */
- if(Obj=(Object *)DoSuperMethodA(cl,o,msg))
- unless(GetREKO(cb,Obj,((struct opSet *)msg)->ops_AttrList))
- {
- CoerceMethod(cl,Obj,OM_DISPOSE);
- return(NULL);
- }
- break;
- default: /* Let the superclass handle it */
- Obj=(Object *)DoSuperMethodA(cl,o,msg);
- break;
- }
- return(Obj);
- }
-
- STATIC LBOOL GetREKO(struct ClassBase *cb, Object *o, struct TagItem *attrs)
- {
- struct RekoHeader Header;
- struct BitMapHeader *BMHD=NULL;
- struct BitMap *BM;
- struct ColorRegister *CMAP=NULL;
- LONG *CRegs=NULL;
-
- MPTR Buffer,SrcPtr; /* Buffer for reading */
- STRPTR Title; /* Picture name */
- BPTR FH=0; /* File handle */
- ULONG ModeID; /* Display mode */
- ULONG HCnt,Cards,Height,Width,Depth,LSize,CSize;
- ULONG BPR,DstOffs,X,Y,I,J,K;
-
- /* Get default title */
- Title=(STRPTR)GetTagData(DTA_Name,NULL,attrs);
-
- /* Get file handle and BitMapHeader */
- LocGetDTAttrs(cb,o,DTA_Handle,&FH,PDTA_BitMapHeader,&BMHD,TAG_DONE);
- try(FH && BMHD, EXIT) /* File handle or header not supplied */
- try(Seek(FH,0,OFFSET_BEGINNING)>=0, EXIT); /* Position at the beginnig of file */
- try(Read(FH,&Header,HEADER_SIZE)==HEADER_SIZE, EXIT);
- if(Header.rh_ID!=REKO_ID) /* Not REKO */
- {
- SetIoErr(ERROR_OBJECT_WRONG_TYPE); /* Inform caller */
- throw(EXIT);
- }
-
- /* Calculate sizes */
- Width=Header.rh_Width;
- Height=Header.rh_Height;
- Depth=Header.rh_Depth;
- Cards=Header.rh_Cards;
- LSize=Width>>3; /* Width in bytes */
- CSize=LSize*Height*Depth; /* Card size in bytes */
- if(Header.rh_SingleSize!=CSize ||
- Header.rh_BodySize!=CSize*Cards+CTABLE_SIZE || Cards==0)
- { /* Do internal checking */
- SetIoErr(ERROR_OBJECT_WRONG_TYPE); /* Inform caller */
- throw(EXIT);
- }
-
- /* Calculate number of horizonatal cards */
- HCnt=(Cards==REKO_I) ? 14 :
- ((Cards==REKO_II) ? 16 : Cards/VCNT+(Cards%VCNT>0));
- BMHD->bmh_Width=Width*HCnt; /* Fill in informations */
- BMHD->bmh_Height=Height*VCNT;
- BMHD->bmh_Depth=Depth;
-
- /* Get display mode id */
- if(ModeNotAvailable(Header.rh_ModeID)==0) /* Good mode */
- ModeID=Header.rh_ModeID;
- else /* Calculate mode */
- {
- ModeID=BestModeID(BIDTAG_DIPFMustHave, DIPF_IS_HAM,
- BIDTAG_DesiredWidth, BMHD->bmh_Width,
- BIDTAG_DesiredHeight, BMHD->bmh_Height,
- BIDTAG_Depth, BMHD->bmh_Depth,
- BIDTAG_SourceID, HIRESHAMLACE_KEY,TAG_DONE);
- if(ModeID==INVALID_ID)
- ModeID=HIRESHAMLACE_KEY;
- }
-
- /* Get colors */
- LocSetDTAttrs(cb,o,PDTA_NumColors,1<<BMHD->bmh_Depth,TAG_DONE);
- LocGetDTAttrs(cb,o,PDTA_ColorRegisters,&CMAP,PDTA_CRegs,&CRegs,TAG_DONE);
- try(CMAP && CRegs, EXIT);
- try(Read(FH,CMAP,CTABLE_SIZE)==CTABLE_SIZE, EXIT);
- /* Set remap palette */
- for(I=0; I<1<<BMHD->bmh_Depth; I++)
- {
- CRegs[I*3+0]=CMAP[I].red<<24;
- CRegs[I*3+1]=CMAP[I].green<<24;
- CRegs[I*3+2]=CMAP[I].blue<<24;
- }
-
- /* Prepare bitmap */
- try(BM=AllocBitMap(BMHD->bmh_Width,BMHD->bmh_Height,BMHD->bmh_Depth,
- BMF_CLEAR | BMF_INTERLEAVED | BMF_DISPLAYABLE,NULL),
- NO_BITMAP);
- BPR=BM->BytesPerRow;
-
- /* Read data */
- try(Buffer=AllocVec(CSize,MEMF_PUBLIC), NO_MEM);
- for(I=0; I<Cards; I++)
- {
- try(Read(FH,Buffer,CSize)==CSize, BODY_ERR);
- GetXY(I,&X,&Y); /* Get coordinates */
- SrcPtr=Buffer;
- DstOffs=Y*Height*BPR+X*LSize;
- for(J=0; J<Height; J++)
- {
- for(K=0; K<Depth; K++)
- {
- memcpy(BM->Planes[K]+DstOffs,SrcPtr,LSize);
- SrcPtr+=LSize;
- }
- DstOffs+=BPR;
- }
- }
- FreeVec(Buffer);
-
- /* Set attributes of destination picture */
- LocSetDTAttrs(cb,o,DTA_ObjName,Title,
- DTA_NominalHoriz, BMHD->bmh_Width,
- DTA_NominalVert, BMHD->bmh_Height,
- PDTA_BitMap, BM,
- PDTA_ModeID, ModeID,
- TAG_DONE);
- return(TRUE);
-
- /* Exceptions */
- except(BODY_ERR, );
- except(NO_MEM, FreeVec(Buffer));
- except(NO_BITMAP, FreeBitMap(BM));
- except(EXIT, );
- return(FALSE);
- } /* GetREKO */
-
- STATIC VOID GetXY(ULONG num, ULONG *x, ULONG *y)
- {
- STATIC CONST struct Map Mapping[]=
- {
- {HCNT,0}, {HCNT,1}, {HCNT,1},
- {HCNT,3}, {HCNT+1,3}, {HCNT+2,3}, {HCNT,2}
- };
-
- if(num<3)
- {
- *x=Mapping[num].map_X;
- *y=Mapping[num].map_Y;
- }
- else if(num>54 && num<59)
- {
- *x=Mapping[num-52].map_X;
- *y=Mapping[num-52].map_Y;
- }
- else
- {
- *x=(num-3)/VCNT;
- *y=(num-3)%VCNT;
- }
- } /* GetXY */
-
- STATIC ULONG LocSetDTAttrs(struct ClassBase *cb, Object *o, ULONG data, ...)
- {
- return(SetDTAttrsA(o,NULL,NULL,(struct TagItem *)&data));
- } /* LocSetDTAttrs */
-
- STATIC ULONG LocGetDTAttrs(struct ClassBase *cb, Object *o, ULONG data, ...)
- {
- return(GetDTAttrsA(o,(struct TagItem *)&data));
- } /* LocGetDTAttrs */
-